package semantico;

import Utils.PrintCollor;
import Utils.TipoProducao;
import Utils.Token;
import java.util.ArrayList;
import org.fusesource.jansi.Ansi;

public class TabelaSimbolos {

    protected ArrayList<Simbolo> simbolos;

    public TabelaSimbolos() {
        this.simbolos = new ArrayList<>();
    }

    public boolean possoUsar(String string) {
        return true;
    }

    public void add(Simbolo simbolo) {
        this.simbolos.add(simbolo);
    }

    public boolean addMetodo(String valor) {
        return true;
    }

    @Override
    public String toString() {
        String conteudo = "";
        PrintCollor.print(Ansi.Color.BLUE, getCelular("VALOR")
                + getCelular("TIPO")
                + getCelular("ESCOPO"));
        for (Simbolo simbolo : this.simbolos) {
            conteudo = conteudo
                    + getCelular(simbolo.getValor()) + getCelular("" + simbolo.getTipo())
                    + getCelular("" + simbolo.getEscopo()) + "\n";
        }
        return conteudo;
    }

    public String getCelular(String texto) {
        int tamanho = texto.toCharArray().length;
        if (tamanho < 25) {
            for (int i = 0; i < 30 - tamanho; i++) {
                texto = texto + " ";
            }
        }
        return texto;
    }

    public void setType(EnumTipo tokenTipo) {
        for (Simbolo simbolo : this.simbolos) {
            if (simbolo.getTipo() == EnumTipo.NULO) {
                simbolo.setTipo(tokenTipo);
            }
        }
    }

    public void imprimeEstados(ArrayList<Token> tokens) {
        for (Token token : tokens) {
            PrintCollor.print(Ansi.Color.RED, "Index: " + tokens.indexOf(token) + " - " + token);
        }
    }

    public boolean isValido(Token tokenSemantico, ArrayList<Token> expressao) {
        boolean resultado = true;
        //imprimeEstados(expressao);
        switch (this.getSimboloByValor(tokenSemantico.getValor()).getTipo()) {
            case BOOLEAN:
                for (Token token : expressao) {
                    if ((token.getTipo() != TipoProducao.FECHA_PARENTESE)
                            && (token.getTipo() != TipoProducao.FECHA_PARENTESE)
                            && (token.getTipo() != TipoProducao.IDENTIFIER)
                            && (token.getTipo() != TipoProducao.DOIS_PONTOS_IGUAL)) {
                        resultado = false;
                    }

                }
                return resultado;
            case ALFA:
                for (Token token : expressao) {
                }
                return true;
            case CHAR:
                for (Token token : expressao) {
                    if ((token.getTipo() != TipoProducao.FECHA_PARENTESE)
                            && (token.getTipo() != TipoProducao.FECHA_PARENTESE)
                            && (token.getTipo() != TipoProducao.IDENTIFIER)
                            && (token.getTipo() != TipoProducao.ASPAS_DUPLAS)
                            && (token.getTipo() != TipoProducao.ASPAS_SIMPLES)
                            && (token.getTipo() != TipoProducao.DOIS_PONTOS_IGUAL)) {
                        resultado = false;
                    }
                }
                return resultado;
            case INTEGER:
                for (Token token : expressao) {
                    if ((token.getTipo() != TipoProducao.FECHA_PARENTESE)
                            && (token.getTipo() != TipoProducao.FECHA_PARENTESE)
                            && (token.getTipo() != TipoProducao.IDENTIFIER)
                            && (token.getTipo() != TipoProducao.SOMAR)
                            && (token.getTipo() != TipoProducao.DIV)
                            && (token.getTipo() != TipoProducao.ASTERISCO)
                            && (token.getTipo() != TipoProducao.SUBRITAIR)
                            && (token.getTipo() != TipoProducao.DOIS_PONTOS_IGUAL)) {
                        resultado = false;
                    }
                }
                return resultado;
            case REAL:
                for (Token token : expressao) {
                    if ((token.getTipo() != TipoProducao.FECHA_PARENTESE)
                            && (token.getTipo() != TipoProducao.FECHA_PARENTESE)
                            && (token.getTipo() != TipoProducao.IDENTIFIER)
                            && (token.getTipo() != TipoProducao.SOMAR)
                            && (token.getTipo() != TipoProducao.DIV)
                            && (token.getTipo() != TipoProducao.ASTERISCO)
                            && (token.getTipo() != TipoProducao.SUBRITAIR)
                            && (token.getTipo() != TipoProducao.DOIS_PONTOS_IGUAL)) {
                        resultado = false;
                    }
                }
                return resultado;
        }
        return true;
    }

    private Simbolo getSimboloByValor(String valor) {
        for (Simbolo simbolo : this.simbolos) {
            if (simbolo.getValor().equals(valor)) {
                return simbolo;
            }
        }
        return new Simbolo(null, EnumTipo.REAL, 0);
    }

}
